#include "EulerCamera.h"

#define  _USE_MATH_DEFINES
#include <math.h>

EulerCamera::EulerCamera(DirectX::XMFLOAT3 position, DirectX::XMFLOAT3 eulerRotation) : Camera(position), m_eulerAngles(eulerRotation)
{
}

EulerCamera::~EulerCamera(void)
{
}

DirectX::XMMATRIX EulerCamera::GetViewMatrix( void )
{
	return DirectX::XMMatrixInverse(nullptr, m_translation)
		* DirectX::XMMatrixInverse(nullptr, m_GetRotationMatrix());
}

DirectX::XMMATRIX EulerCamera::GetCameraTransform( void )
{
	return m_GetRotationMatrix() * m_translation;
}

Snapshot EulerCamera::GetSnapshot( void )
{
	Snapshot snapshot;
	snapshot.translation = m_translation;
	DirectX::XMVECTOR quaternion = DirectX::XMQuaternionRotationRollPitchYaw(m_eulerAngles.x, m_eulerAngles.y, m_eulerAngles.z);
	DirectX::XMStoreFloat4(&snapshot.rotation, quaternion);
	return snapshot;
}

DirectX::XMMATRIX EulerCamera::m_GetRotationMatrix( void )
{
	return DirectX::XMMatrixRotationRollPitchYaw(m_eulerAngles.x, m_eulerAngles.y, m_eulerAngles.z);
}

void EulerCamera::AddRotation( DirectX::XMFLOAT3 eulerRotation )
{
	m_eulerAngles.x = static_cast<float>(std::fmod((m_eulerAngles.x + eulerRotation.x), (2 * M_PI)));
	m_eulerAngles.y = static_cast<float>(std::fmod((m_eulerAngles.y + eulerRotation.y), (2 * M_PI)));
	m_eulerAngles.z = static_cast<float>(std::fmod((m_eulerAngles.z + eulerRotation.z), (2 * M_PI)));
}

void EulerCamera::Move( DirectX::XMFLOAT3 movement )
{
	XMStoreFloat3(&movement, XMVector3Transform(XMLoadFloat3(&movement), m_GetRotationMatrix()));
	MoveRotationIndependent(movement);
}

void EulerCamera::MoveRotationIndependent( DirectX::XMFLOAT3 movement )
{
	m_translation *= DirectX::XMMatrixTranslation(movement.x, movement.y, movement.z);
}
